Definindo Fixtures
=================

Testes automatizados precisam ser executados muitas vezes. Para nos assegurarmos
de que o processo de testes é repetível, gostaríamos de rodar os testes em algum
estado conhecido chamado *fixture*. Por exemplo, para testar a funcionalidade de
criação de posts em uma aplicação de blog, toda vez que rodarmos os testes, as
tabelas armazenando os dados relevantes sobre posts (por exemplo, a tabela
`Post`, a tabela `Comentario`) devem ser restauradas a algum estado fixo. A
[documentação do PHPUnit](http://www.phpunit.de/manual/current/en/fixtures.html)
explicou bem a definição de fixtures genéricas. Nesta seção, descrevemos
principalmente como configurar fixtures de banco de dados, como acabamos de
descrever no exemplo.

Configurar fixtures de banco de dados talvez seja uma das partes mais demoradas
ao testar aplicações Web com banco de dados. O Yii introduz o componente de
aplicação [CDbFixtureManager] para aliviar este problema. Ele basicamente faz
as seguintes coisas ao rodar um conjunto de testes:

 * Antes que todos os testes rodem, ele reseta a algum estado conhecido todas as
   tabelas relevantes para os testes.
 * Antes que um único método de teste rode, ele reseta as tabelas especificadas
   para algum estado conhecido.
 * Durante a execução de um método de teste, fornece acesso às linhas dos dados
   que contribuem com a fixture.

Para utilizar o [CDbFixtureManager], nós o configuramos na
[configuração da aplicação](/doc/guide/basics.application#application-configuration),
conforme segue,

~~~
[php]
return array(
	'components'=>array(
		'fixture'=>array(
			'class'=>'system.test.CDbFixtureManager',
		),
	),
);
~~~

Então fornecemos dados à fixture no diretório `protected/tests/fixtures`. Este
diretório pode ser personalizado para apontar para um diferente configurando-se
a propriedade [CDbFixtureManager::basePath] na configuração da aplicação. Os
dados da fixture são organizados como uma coleção de arquivos PHP chamados de
arquivos de fixtures. Cada arquivo de fixture retorna um array representando as
linhas de dados iniciais para uma tabela em particular. O nome do arquivo é o
mesmo que o nome da tabela. Segue um exemplo de dados de fixture para a tabela
`Post`, armazenados em um arquivo chamado `Post.php`:

~~~
[php]
<?php
return array(
	'exemplo1'=>array(
		'titulo'=>'post de testes 1',
		'conteudo'=>'conteúdo do post de testes 1',
		'dataCriacao'=>1230952187,
		'autorId'=>1,
	),
	'exemplo2'=>array(
		'titulo'=>'post de testes 2',
		'conteudo'=>'conteúdo do post de testes 2',
		'dataCriacao'=>1230952287,
		'autorId'=>1,
	),
);
~~~

Como podemos perceber, duas linhas de dados são retornadas no exemplo acima.
Cada linha é representada como um array associativo cujas chaves são nomes de
colunas e cujos valores são os valores das colunas correspondentes. Além disso,
cada linha é indexada por uma string (`exemplo1`, `exemplo2`) que é chamada
de *alias de linha*. Mais tarde, quando escrevermos os scripts de testes,
podemos convenientemente nos referir a uma linha por seu alias. Descreveremos
isso em detalhes na próxima seção.

Você pode notar que nós não especificamos os valores da coluna `id` na fixture
acima. Isso porque a coluna `id` está definida como uma chave primária
auto-incrementável cujo valor será preenchido quando inserimos novas linhas.

Quando o [CDbFixtureManager] é referenciado pela primeira vez, ele percorrerá
todos os arquivos de fixture e os usará para resetar as tabelas correspondentes.
Ele reseta uma tabela truncando a mesma, resetando o valor da sequence da chave
primária auto-incrementável, e então inserindo na tabela as linhas de dados do
arquivo de fixture.

Algumas vezes podemos não querer resetar todas as tabelas que têm um arquivo de
fixture antes de rodarmos um conjunto de testes, porque resetar muitos arquivos
de fixtures pode demorar bastante tempo. Neste caso, podemos escrever um script
PHP para fazer o trabalho de inicialização de uma forma personalizada. O script
deve ser salvo em um arquivo chamado de `init.php` sob o mesmo diretório que
contém os outros arquivos de fixtures. Quando o [CDbFixtureManager] detecta a
existência deste script, ele o executará ao invés de resetar todas as tabelas.

Também é possível que nós não gostemos da maneira padrão de resetar uma tabela,
ou seja, truncá-la e inserir os dados de fixture. Se este for o caso, podemos
escrever um script de inicialização específico para o arquivo de fixture. O
script deve ser nomeado com o nome da tabela com o sufixo `.init.php`. Por
exemplo, o script de inicialização da tabela `Post` seria `Post.init.php`.
Quando o [CDbFixtureManager] vê este script, ele o executa ao invés de usar o
jeito padrão de resetar a tabela.

> Tip|Dica: Ter fixtures demais pode aumentar consideravelmente o tempo de
testes. Por esse motivo, você só deve fornecer arquivos de fixture para as
tabelas cujo conteúdo pode mudar durante o teste. Tabelas que só servem para 
consulta não mudam, e portanto não precisam de arquivos de fixture.

Nas próximas duas seções, descreveremos como utilizar as fixtures gerenciadas
pelo [CDbFixtureManager] em testes unitários e funcionais.

<div class="revision">$Id$</div>